class GameBoard < Gtk::DrawingArea

	attr_reader :drawingArea

	def initialize(_gameplay, _scale)
		
		super()

		@gameplay = _gameplay
		@map = @gameplay.map
		@scale = _scale.to_f
				
		@adjustEdges = 0.2 * @scale
		
		@hMap = Map.new(@map.width+1, @map.height+1)
		@vMap = Map.new(@map.width+1, @map.height+1)
		
		@playerColours = []

		
		#make these part of the country class?
		#don't think so since country shouldn't care about how/if drawing is done
		#but perhaps some kind of data type
		#all these values floating around as class variables seems bulky
		@paths = []				#drawing paths for each country
		@centres = []			#centre x,y point for writing text per country
		
		self.set_size_request(@map.width*@scale, @map.height*@scale)

		self.signal_connect("expose_event") do

			@context = self.window.create_cairo_context
			@context.set_line_join(Cairo::LINE_JOIN_ROUND)
			@context.set_line_width(0.07*@scale)
			
						
			#water
			@context.set_source_rgb(0.125, 0.29, 0.53)
			@context.rectangle( 0, 0, (@map.width)*@scale, (@map.height)*@scale )
			@context.fill
			
			for country in (1..@map.countryCount)
			
				outline(country, @context)

			end
			
			for country in (1..@map.countryCount)
			
				putTroops(country-1, @context)

			end
			@context.stroke


			
	
							   
		end
	
	end
	
	
	
	def hLine(smap, _x, _y, reverseDir, cc, started)
	
		if not reverseDir
			x = @scale
		else
			x = -@scale
		end
		
		
		#cc.rel_line_to(x, 0)
		
		if reverseDir
			drawHLine(smap, _x,_y,cc, true, started)
			#@cc.line_to(tx, ty)
		else
			drawHLine(smap, _x,_y, cc, false, started)
		end

	
	end
	
	def vLine(smap, _x, _y, reverseDir, cc, started)
	
		if not reverseDir
			y = @scale
		else
			y = -@scale
		end		
		
		#cc.line_to(x*@scale, ty*@scale)
		if reverseDir
			drawVLine(smap, _x,_y, cc, true, started)
			#cc.line_to(tx, ty)
		else
			drawVLine(smap, _x,_y, cc, false, started)
		end
	
	end
	
	
	def outline(country, cc)
	
		if @paths[country] == nil
		
			smap = getCountryMap(country)
		
			start = findCountryEdgePoint(country)
			
			x = start[0]
			y = start[1]
			
			startX = x
			startY = y
			
			cc.move_to(x*@scale, y*@scale)
			
			
			
			h = 1
			v = 2
			d = h
			
			started = false
			
			while (x != startX or y != startY) or not started
				
				dirs = [h, v, -h, -v]
				

				
				cycleToValue(-d, dirs)
				advance(dirs)
				advanceCount = 1
				
				done = false
				
				while advanceCount < 4 and not done
				
					if dirs[0] == h
						
						if not same(country, smap, x, y-1, x, y)
						

							hLine(smap, x, y, false, cc, started)
							
							x += 1
							done = true
												
							advanceCount = 0
							d=dirs[0]
							
						else
						
							advance(dirs)
							advanceCount += 1
						
						end
						
						
					elsif dirs[0] == v
					
						if not same(country, smap, x-1, y, x, y)
						
							vLine(smap, x, y, false, cc, started)

							y += 1
							done = true
							
							advanceCount = 0
							d=dirs[0]
							
						else
						
							advance(dirs)
							advanceCount += 1
							
						end
						
					elsif dirs[0] == -h
					
						if not same(country, smap, x-1, y, x-1, y-1)
						
							hLine(smap, x, y, true, cc, started)
						
							x -= 1				
							done = true
							
							advanceCount = 0
							d=dirs[0]
							
						else
						
							advance(dirs)
							advanceCount += 1
							
						end
						
					elsif dirs[0] == -v
					
						if not same(country, smap, x-1, y-1, x, y-1)
						
							vLine(smap, x, y, true, cc, started)
						
							y -= 1
							done = true
							
							advanceCount = 0
							d=dirs[0]
							
						else
						
							advance(dirs)
							advanceCount += 1
							
						end
						
					end
					
				end #while advanceCount < 4 and not done
				
				started = true
				
			end #while x != startX ...
			@paths[country] = @context.copy_path
			
		else
			@context.append_path(@paths[country])
		end
		
		owner = @gameplay.countries[country-1].owner
		owner = 0 if owner == nil
		if owner > 0
			r = @playerColours[owner][0]
			g = @playerColours[owner][1]
			b = @playerColours[owner][2]
			cc.set_source_rgb(r, g, b)
		else
			cc.set_source_rgb(0.533, 0.541, 0.52)
		end
		


		
		cc.fill_preserve
		
		cc.set_source_rgb(0.0, 0.0, 0.0)
		cc.stroke
		
	
	end
	
	
	def getCountryMap(country)
	
		smap = Map.new(@map.width, @map.height)
		
		for x in (0..@map.width-1)
			for y in (0..@map.height-1)
		
				if @map.cell(x, y) == country
					smap.setCell(x, y, country)
				else
					#smap.setCell(x, y, TILE_INVALID)
					smap.setCell(x, y, @map.cell(x,y))
				end
		
			end
		end
		
		return smap
		
	end
		
	def same(country, smap, x1, y1, x2, y2)
	
		if smap.cell(x1, y1) == smap.cell(x2, y2) and smap.cell(x1, y1) == country
			return true
		elsif smap.cell(x1, y1) != country and smap.cell(x2, y2) == TILE_INVALID
			return true
		elsif smap.cell(x2, y2) != country and smap.cell(x1, y1) == TILE_INVALID
			return true
		elsif smap.cell(x1, y1) != country and smap.cell(x2, y2) != country
			return true
		else
			return false
		end
	
	end
	
	def oldsame(country, smap, x1, y1, x2, y2)
	
		if smap.cell(x1, y1) == smap.cell(x2, y2) and smap.cell(x1, y1) != TILE_INVALID
			return true
		elsif smap.cell(x1, y1) != country and smap.cell(x2, y2) == TILE_INVALID
			return true
		elsif smap.cell(x2, y2) != country and smap.cell(x1, y1) == TILE_INVALID
			return true
		else
			return false
		end
	
	end
	
	def cycleToValue(value, array)
	
		while array.first != value
			array << array.shift
		end
	
	end
	
	def advance(array)
	
		array << array.shift
	
	end
	
	
	
	
	
	def drawVLine(smap, _x,_y, cc, reverse, started)
	
		x = _x
		y = _y
		
		y -= 1 if reverse
	
		#if x != 0

			#@context.move_to( x*@scale, y*@scale )
			#@context.line_to( x*@scale, (y+1)*@scale )
			
			tAdjust = [0, 0]
			bAdjust = [0, 0]

			hint = 0

			#top right corner
			if smap.cell(x-1, y) != smap.cell(x, y) and smap.cell(x, y) == smap.cell(x-1, y-1) #and smap.cell(x-1, y) != TILE_INVALID
				tAdjust = [-@adjustEdges, @adjustEdges]
				hint = 1
			end
			
			#top left corner
			if smap.cell(x, y) != smap.cell(x-1, y) and smap.cell(x-1, y) == smap.cell(x, y-1) #and smap.cell(x, y) != TILE_INVALID
				tAdjust = [@adjustEdges, @adjustEdges]
				hint = 2
			end
			
			#bottom right corner
			if smap.cell(x-1, y) != smap.cell(x, y) and smap.cell(x, y) == smap.cell(x-1, y+1) #and smap.cell(x-1, y) != TILE_INVALID
				bAdjust = [-@adjustEdges, -@adjustEdges]
				hint = 3
			end

			#bottom left corner
			if smap.cell(x-1, y) != smap.cell(x, y) and smap.cell(x, y+1) == smap.cell(x-1, y) #and smap.cell(x, y) != TILE_INVALID
				bAdjust = [@adjustEdges, -@adjustEdges]
				hint = 4
			end
			
			if not started
				cc.move_to( x*@scale + tAdjust[0], y*@scale + tAdjust[1] )
			end


			if @vMap.cell(x, y) == TILE_COASTLINE

				cy1 = rand(@scale/2.0)/@scale
				cy2 = rand(@scale/2.0)/@scale
				cy3 = rand(@scale/2.0)/@scale
				cy4 = rand(@scale/2.0)/@scale
				cx1 = rand(@scale/2.0).to_f
				cx2 = rand(@scale/2.0).to_f
				cx3 = rand(@scale/2.0).to_f
				cx4 = rand(@scale/2.0).to_f
				@vMap.setCell(x, y, [cx1, cx2, cx3, cx4, cy1, cy2, cy3, cy4])
			else
			
				randValues = @vMap.cell(x, y)
				cx1 = randValues[0].to_f
				cx2 = randValues[1].to_f
				cx3 = randValues[2].to_f
				cx4 = randValues[3].to_f
				cy1 = randValues[4].to_f
				cy2 = randValues[5].to_f
				cy3 = randValues[6].to_f
				cy4 = randValues[7].to_f
			
			end


			if not reverse
				#cc.rel_line_to(-tAdjust[0], @scale/2.0-tAdjust[1])
				#cc.rel_line_to(+bAdjust[0], @scale/2.0+bAdjust[1])
				cc.rel_curve_to( -@scale/4.0+cx1, cy1, -@scale/4.0+cx2, 0.5+cy2, -tAdjust[0], @scale/2.0-tAdjust[1])
				cc.rel_curve_to( -@scale/4.0+cx3, cy3, -@scale/4.0+cx4, 0.5+cy4, +bAdjust[0], @scale/2.0+bAdjust[1])
			else
				#cc.rel_line_to(-bAdjust[0], -@scale/2.0-bAdjust[1])
				#cc.rel_line_to(+tAdjust[0], -@scale/2.0+tAdjust[1])
				cc.rel_curve_to( -@scale/4.0+cx4, -(cy4), -@scale/4.0+cx3, -(0.5+cy3), -bAdjust[0], -@scale/2.0-bAdjust[1] )
				cc.rel_curve_to( -@scale/4.0+cx2, -(cy2), -@scale/4.0+cx1, -(0.5+cy1), +tAdjust[0], -@scale/2.0+tAdjust[1] )
			end
		

		#end
	
		return hint
	end

	def drawHLine(smap, _x, _y, cc, reverse, started)
	
		x = _x
		y = _y
		
		x -= 1 if reverse
	
		#if y != 0
		
			#@context.move_to( x*@scale , y*@scale )
			#@context.line_to( (x+1)*@scale, y*@scale )
			
			
			rAdjust = [0, 0]
			lAdjust = [0, 0]
			
			hint = []

			#top right corner
			if smap.cell(x, y) != smap.cell(x+1, y) and smap.cell(x+1, y) == smap.cell(x, y-1) #and smap.cell(x, y) != TILE_INVALID
				rAdjust = [-@adjustEdges, @adjustEdges]
			end
			
			#top left corner
			if smap.cell(x-1, y) != smap.cell(x, y) and smap.cell(x-1, y) == smap.cell(x, y-1) #and smap.cell(x, y) != TILE_INVALID
				lAdjust = [@adjustEdges, @adjustEdges]
			end

			#bottom right corner
			if smap.cell(x, y) != smap.cell(x, y-1) and smap.cell(x, y) == smap.cell(x+1, y-1) #and smap.cell(x, y-1) != TILE_INVALID
				rAdjust = [-@adjustEdges, -@adjustEdges]
			end
			
			#bottom left corner
			if smap.cell(x, y) != smap.cell(x, y-1) and smap.cell(x, y) == smap.cell(x-1, y-1) #and smap.cell(x, y-1) != TILE_INVALID
				lAdjust = [@adjustEdges, -@adjustEdges]
			end
			
			if not started
				cc.move_to( x*@scale + lAdjust[0], y*@scale + lAdjust[1] )
			end


			if @hMap.cell(x, y) == TILE_COASTLINE

				cx1 = rand(@scale/2.0)/@scale
				cx2 = rand(@scale/2.0)/@scale
				cx3 = rand(@scale/2.0)/@scale
				cx4 = rand(@scale/2.0)/@scale
				cy1 = rand(@scale/2.0).to_f
				cy2 = rand(@scale/2.0).to_f
				cy3 = rand(@scale/2.0).to_f
				cy4 = rand(@scale/2.0).to_f
				@hMap.setCell(x, y, [cx1, cx2, cx3, cx4, cy1, cy2, cy3, cy4])
			else
			
				randValues = @hMap.cell(x, y)
				cx1 = randValues[0].to_f
				cx2 = randValues[1].to_f
				cx3 = randValues[2].to_f
				cx4 = randValues[3].to_f
				cy1 = randValues[4].to_f
				cy2 = randValues[5].to_f
				cy3 = randValues[6].to_f
				cy4 = randValues[7].to_f
			
			end

			if not reverse
				#cc.rel_line_to(@scale/2.0-lAdjust[0], -lAdjust[1])
				#cc.rel_line_to(@scale/2.0+rAdjust[0], +rAdjust[1])
				cc.rel_curve_to( cx1, -@scale/4.0+cy1, 0.5+cx2, -@scale/4.0+cy2, @scale/2.0-lAdjust[0], -lAdjust[1])
				cc.rel_curve_to( cx3, -@scale/4.0+cy3, 0.5+cx4, -@scale/4.0+cy4, @scale/2.0+rAdjust[0], rAdjust[1])
			else
				#cc.rel_line_to(-@scale/2.0-rAdjust[0], -rAdjust[1])
				#cc.rel_line_to(-@scale/2.0+lAdjust[0], +lAdjust[1])
				cc.rel_curve_to( -(cx4), -@scale/4.0+cy4, -(0.5+cx3), -@scale/4.0+cy3, -@scale/2.0-rAdjust[0], -rAdjust[1])
				cc.rel_curve_to( -(cx2), -@scale/4.0+cy2, -(0.5+cx1), -@scale/4.0+cy1, -@scale/2.0+lAdjust[0], lAdjust[1])			
			end

		#end
		
		return hint
	end
	
	
	def findCountryEdgePoint(country)
	
	
		for x in (0..@map.width)
			for y in (0..@map.height)
			
				if @map.cell(x,y) == country
					return [x,y]
				end
			
			end
		end
		
	end
	
	
	def setPlayerColour(player, r, g, b)
		@playerColours[player] = [r,g,b]
	end
	
	
	def putTroops(country, cc)
		
		t = @gameplay.countries[country].troops
		return if t == 0
		
		if @centres[country] == nil
			@centres[country] = getCentreOfRegion(country)
		end
			
		cc.move_to(@centres[country][0] * @scale, @centres[country][1] * @scale)
		cc.set_source_rgb(1, 1, 1)
		cc.show_text(t.to_s)
	
	end
	
	
	def getCentreOfRegion(country)
		
		ax = 0.0
		ay = 0.0
		count = 0
		
	
		for x in (0..@map.width)
			for y in (0..@map.height)
			
				if @map.cell(x,y)-1 == country
					ax += x.to_f
					ay += y.to_f
					count += 1
				end
			
			end
		end
		
		return [ax/count.to_f, ay/count.to_f]
	
	end

end
